package com.vmix.android.vmixsdk.rds;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.http.HttpException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import org.w3c.dom.Element;
import org.xml.sax.InputSource;

import android.util.Log;

import com.vmix.android.vmixsdk.config.VmixConfig;
import com.vmix.android.vmixsdk.exception.VmixException;
import com.vmix.android.vmixsdk.valueobject.VmixVideo;
import com.vmix.android.vmixsdk.valueobject.VmixVideos;

public class GetCollectionMediasOperation extends AbstractOperation {

	protected String action = "getCollectionMedias";
	
	private String collectionId;
	private String formatId;
	
	/**
	 * get a list of medias in the specified collection
	 * 
	 * @param collectionId
	 * @throws VmixException
	 */
	public GetCollectionMediasOperation( String collectionId) throws VmixException {
		
		if( VmixConfig.COLLECTION.length() < 1 ) {
			
			throw new VmixException("Missing COLLECTION service URL in VmixConfig");
		}
		
		if( VmixConfig.ATOKEN.length() < 1 ) {
			
			throw new VmixException("Missing ATOKEN in VmixConfig");
			
		}
	
		this.serviceUrl = VmixConfig.COLLECTION;
	
		this.collectionId = collectionId;
		this.formatId = VmixConfig.DEFAULT_FORMAT;
	}
	
	public GetCollectionMediasOperation( String collectionId, String formatId ) throws VmixException {
		
		if( VmixConfig.COLLECTION.length() < 1 ) {
			
			throw new VmixException("Missing COLLECTION service URL in VmixConfig");
		}
		
		if( VmixConfig.ATOKEN.length() < 1 ) {
			
			throw new VmixException("Missing ATOKEN in VmixConfig");
			
		}
	
		this.serviceUrl = VmixConfig.COLLECTION;
	
		this.collectionId = collectionId;
		this.formatId = formatId;
	}
	
	/**
	 * execute the getCollectionMedias operation
	 * 
	 * @return
	 * @throws VmixException
	 */
	public VmixVideos process() throws VmixException {
		
		// build out the request url
		this.serviceUrl += "action=" + this.action + "&collection_id="+ this.collectionId 
			+ "&atoken="+ VmixConfig.ATOKEN+"&output=xml";

		Log.v("MEDIAS", this.serviceUrl);
		VmixVideos videos = new VmixVideos();
		
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		
		try {

			// build out new url object
			URL url = new URL( this.serviceUrl );
			URLConnection connection = url.openConnection();
			
			HttpURLConnection httpConnection = (HttpURLConnection)connection;
			
			// get respone code
			int responseCode = httpConnection.getResponseCode();
			
			// if the response code is not ok
			if( responseCode != HttpURLConnection.HTTP_OK ) {
				throw new HttpException("NO RESPONSE");
			}
			
			// get input stream
			InputStream inputStream = httpConnection.getInputStream();
			// let's make sure that we handle the UTF8 properly
			InputSource inputSource = new InputSource(new InputStreamReader(inputStream, "UTF-8"));
			DocumentBuilder builder = factory.newDocumentBuilder();
			
			Document dom = builder.parse( inputSource );
			Element root = dom.getDocumentElement();
			NodeList items = root.getElementsByTagName("media"); 
			
			for( int i = 0; i < items.getLength(); i++ ) {

				VmixVideo video = new VmixVideo();
				
				// get media item
				Node mediaItem = items.item(i);
				NodeList properties = mediaItem.getChildNodes();
				
				String defaultToken = "";
				
				// get a list of the childnodes
				for( int j = 0; j < properties.getLength(); j++ ) {
					
					// pull out property name and value
					Node property = properties.item(j);
					String propertyName = property.getNodeName();

					// valiate that the first child actually exist, if not we hve no value ?
					Node firstChild = property.getFirstChild();
					if( firstChild == null ) {
						continue;
					}
					
					// set id
					if( propertyName.equalsIgnoreCase("id") ) {
						video.setMediaId((String)firstChild.getNodeValue());
					}
					// set partner id
					else if( propertyName.equalsIgnoreCase("partner_id") ) {
						video.setPartnerId((String)firstChild.getNodeValue());
					}
					// set title
					else if( propertyName.equalsIgnoreCase("title")) {
						video.setTitle((String)firstChild.getNodeValue());
					}
					// set description
					else if( propertyName.equalsIgnoreCase("description") ) {
						// Since description is not a required field, we need to verify that it exists
						/*Node description = property.getFirstChild();
						if( description != null ) {
							video.setDescription((String)description.getNodeValue());
						}*/
						video.setDescription( (String) firstChild.getNodeValue());
					}
					// set class_id
					/*else if( propertyName.equalsIgnoreCase("class_id") ) {
						video.setClassId(propertyValue);
					}
					// set date created
					else if( propertyName.equalsIgnoreCase("date_created") ) {
						video.setDateCreated(propertyValue);
					}
					// set date approved
					else if( propertyName.equalsIgnoreCase("date_approved") ) {
						video.setDateApproved(propertyValue);
					}
					// set last modified
					else if( propertyName.equalsIgnoreCase("date_modified") ) {
						video.setLastModified(propertyValue);
					}
					// set source name
					else if( propertyName.equalsIgnoreCase("source_name") ) {
						video.setSourceName(propertyValue);
					}
					// set total views
					else if( propertyName.equalsIgnoreCase("total_views") ) {
						video.setTotalViews(propertyValue);
					}*/
					// get the default token
					else if( propertyName.equalsIgnoreCase("token" ) ) {
						defaultToken = (String)firstChild.getNodeValue();
					}
					// set the token for the specified format in VmixConfig
					else if( propertyName.equalsIgnoreCase("formats") ) {
						NodeList formats = property.getChildNodes();
			
						// need to loop through these formats to find the one we want
						for ( int k = 0; k < formats.getLength(); k++ ) {
							
							// skip this if the token is set
							if( video.getToken() != null ) {
								// break out of this loop
								break;
							}
							
							Node format = formats.item(k);
							
							NodeList formatDetails = format.getChildNodes();
							NodeList formatList = format.getChildNodes();
							
							for( int l = 0; l < formatDetails.getLength(); l++ ) {
							
								Node formatDetail = formatDetails.item(l);
								
								// if it's format id, check it
								if( formatDetail.getNodeName().equals( "format_id")) {
									
									if( formatDetail.getFirstChild().getNodeValue().equals( this.formatId ) ) {
										
										// TOTAL HACK
										for( int m = 0; m < formatList.getLength(); m++ ) {
											
											Node tokenNode = formatList.item( m );

											if( tokenNode.getNodeName().equals( "token" ) ) {

												video.setToken( (String) tokenNode.getFirstChild().getNodeValue());
												
												break;
											}
										}

										break;
									}
								}
							}
						}
					}
					// set the default thumbnail url
					else if ( propertyName.equalsIgnoreCase("thumbnail") ) {
						//video.setThumbnail( (String) property.getFirstChild().getFirstChild().getNodeValue() );
						NodeList thumbnails = property.getChildNodes();

						// need to loop through these thumbnails to get the defautl value
						for( int l = 0; l< thumbnails.getLength(); l++ ) {
							Node thumbnail = thumbnails.item( l );
							
							if( thumbnail.getNodeName().equals("url") ) {
						
								String imgmanThumbUrl = VmixConfig.IMGMAN + "url=" + (String)thumbnail.getFirstChild().getNodeValue() + "&width=108&height=85&fill=000000000";
								video.setThumbnail( imgmanThumbUrl );
								
							}

						}
					}
				}

				if( video.getToken() == null ) {
					
					video.setToken( defaultToken );
				}

				// add this point we need to figure out whether to add the video
				// into the list
				String mediaId = video.getMediaId();
				
				if( mediaId != null && mediaId.length() > 0 ) {
					
					videos.add( video );
				
				}
			
			}
			
			return videos;
			
		}
		catch( Exception e ) {
			Log.v("MEDIAS", "ERRORS: " + e.getMessage() );
			Log.v("MEDIAS", "TRACE: " + e.getStackTrace().toString() );
			throw new VmixException( e.getMessage() );
		}
		
	}
}
